package com.example.springboottest.example.jedis;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.Tuple;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class JedisZSetDemo {
    /**
     * Zset 有序集合和 Set 集合都是 string 类型元素的集合,且不允许重复的元素。
     * 不同的是 Zset 的每个元素都会关联一个 double 类型的分数，用于从小到大进行排序。
     * 集合是通过哈希表实现的，所以添加，删除，查找的复杂度都是 O(1)。
     * 集合中最大的成员数为 2^32 - 1 (4294967295, 每个集合可存储 40 多亿个元素)。
     */
    public void operateZset() {
        Jedis jedis = new Jedis("localhost");
        jedis.auth("123456");
        System.out.println("jedis.ping (): " + jedis.ping());
        jedis.del("salary");
        Map<String, Double> members = new HashMap<String, Double>();
        members.put("u01", 1000.0);
        members.put("u02", 2000.0);
        members.put("u03", 3000.0);
        members.put("u04", 13000.0);
        members.put("u05", 23000.0);
        //批量添加元素，类型为 java map 映射表
        jedis.zadd("salary", members);
        //type 类型 Zset
        System.out.println("jedis.type(): " + jedis.type("salary"));
        //获取集合元素的个数
        System.out.println("jedis.zcard(): " + jedis.zcard("salary"));
        //按照下标[起,止]遍历元素
        System.out.println("jedis.zrange(): " + jedis.zrange("salary", 0, -1));
        //按照下标[起,止]倒序遍历元素
        System.out.println("jedis.zrevrange(): " + jedis.zrevrange("salary", 0, -1));
        //按照分数（薪资）[起,止]遍历元素
        System.out.println("jedis.zrangeByScore(): " + jedis.zrangeByScore("salary",
                1000, 10000));
        //按照薪资[起,止]遍历元素,带分数返回
        Set<Tuple> res0 = jedis.zrangeByScoreWithScores("salary", 1000, 10000);
        for (Tuple temp : res0) {
            System.out.println("Tuple.get(): " + temp.getElement() + " -> " +
                    temp.getScore());
        }//按照分数[起,止]倒序遍历元素
        System.out.println("jedis.zrevrangeByScore(): "
                + jedis.zrevrangeByScore("salary", 1000, 4000));
        //获取元素[起,止]分数区间的元素数量
        System.out.println("jedis.zcount(): " + jedis.zcount("salary", 1000, 4000));
        //获取元素 score 值：薪资
        System.out.println("jedis.zscore(): " + jedis.zscore("salary", "u01"));
        //获取元素的下标
        System.out.println("jedis.zrank(u01): " + jedis.zrank("salary", "u01"));
        //倒序获取元素的下标
        System.out.println("jedis.zrevrank(u01): " + jedis.zrevrank("salary",
                "u01"));
        //删除元素
        System.out.println("jedis.zrem(): " + jedis.zrem("salary", "u01", "u02"));
        //删除元素,通过下标范围
        System.out.println("jedis.zremrangeByRank(): " +
                jedis.zremrangeByRank("salary", 0, 1));
        //删除元素,通过分数范围
        System.out.println("jedis.zremrangeByScore(): "
                + jedis.zremrangeByScore("salary", 20000, 30000));
        //按照下标[起,止]遍历元素
        System.out.println("jedis.zrange(): " + jedis.zrange("salary", 0, -1));
        Map<String, Double> members2 = new HashMap<String, Double>();
        members2.put("u11", 1136.0);
        members2.put("u12", 2212.0);
        members2.put("u13", 3324.0);
        //批量添加元素
        jedis.zadd("salary", members2);
        //增加指定分数
        System.out.println("jedis.zincrby(10000): " + jedis.zincrby("salary",
                10000, "u13"));
        //按照下标[起,止]遍历元素
        System.out.println("jedis.zrange(): " + jedis.zrange("salary", 0, -1));
        jedis.close();
    }
}